import React, { createContext, useContext, useReducer, useCallback } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { jwtDecode } from 'jwt-decode';
import { AuthState, AuthContextType, User } from './types';
import { userService } from '../../utils/api/services';
import { UserLoginRequest, UserRegisterRequest, UserUpdateRequest } from '../../utils/api/types';
import { storage } from '../../utils/storage';

// 初始状态
const initialState: AuthState = {
  user: null,
  token: null,
  isLoading: true,
  error: null,
};

// 创建上下文
const AuthContext = createContext<AuthContextType | undefined>(undefined);

// 从 token 中获取用户 ID
function getUserIdFromToken(token: string): number | null {
  try {
    const decoded = jwtDecode<{ user_id: number }>(token);
    return decoded.user_id;
  } catch (error) {
    console.error('Failed to decode token:', error);
    return null;
  }
}

// Action 类型
type AuthAction =
  | { type: 'SET_USER'; payload: { user: User; token: string } }
  | { type: 'LOGOUT' }
  | { type: 'SET_LOADING'; payload: boolean }
  | { type: 'SET_ERROR'; payload: string }
  | { type: 'UPDATE_USER'; payload: User };

// Reducer
function authReducer(state: AuthState, action: AuthAction): AuthState {
  switch (action.type) {
    case 'SET_USER':
      return {
        ...state,
        user: action.payload.user,
        token: action.payload.token,
        isLoading: false,
        error: null,
      };
    case 'LOGOUT':
      return {
        ...state,
        user: null,
        token: null,
        isLoading: false,
        error: null,
      };
    case 'SET_LOADING':
      return {
        ...state,
        isLoading: action.payload,
      };
    case 'SET_ERROR':
      return {
        ...state,
        error: action.payload,
        isLoading: false,
      };
    case 'UPDATE_USER':
      return {
        ...state,
        user: action.payload,
      };
    default:
      return state;
  }
}

// Provider 组件
export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [state, dispatch] = useReducer(authReducer, initialState);

  // 初始化检查登录状态
  React.useEffect(() => {
    async function loadStoredAuth() {
      try {
        const [storedUser, storedToken] = await storage.multiGet(['user', 'token']);
        const [, userValue] = storedUser;
        const [, tokenValue] = storedToken;

        if (userValue && tokenValue) {
          dispatch({
            type: 'SET_USER',
            payload: { user: JSON.parse(userValue), token: tokenValue },
          });
        }
      } catch (error) {
        console.error('Failed to load auth state:', error);
      } finally {
        dispatch({ type: 'SET_LOADING', payload: false });
      }
    }

    loadStoredAuth();
  }, []);

  // 登录
  const login = useCallback(async (email: string, password: string) => {
    try {
      const loginData: UserLoginRequest = {
        username_or_email: email,
        password: password,
      };

      const response = await userService.login(loginData);

      if (response.code !== 200) {
        return { 
          success: false, 
          message: response.message || '登录失败'
        };
      }

      const { token } = response.data;

      await storage.setItem('token', token);

      const userId = getUserIdFromToken(token);
      
      if (!userId) {
        return { 
          success: false, 
          message: '登录失败：无效的 token'
        };
      }

      const userResponse = await userService.getUser(userId);
      
      if (userResponse.code !== 200) {
        return { 
          success: false, 
          message: userResponse.message || '获取用户信息失败'
        };
      }

      const user = userResponse.data;

      await Promise.all([
        storage.setItem('user', JSON.stringify(user)),
        storage.setItem('token', token),
      ]);

      dispatch({
        type: 'SET_USER',
        payload: { user, token },
      });

      return { success: true, message: '登录成功' };
    } catch (error: any) {
      console.error('Login error:', error);
      return { 
        success: false, 
        message: error.message || '登录失败，请重试'
      };
    }
  }, []);

  // 登出
  const logout = useCallback(async () => {
    try {
      await userService.logout();
      await storage.multiRemove(['user', 'token']);
      dispatch({ type: 'LOGOUT' });
    } catch (error) {
      console.error('Logout failed:', error);
    }
  }, []);

  // 注册
  const register = useCallback(async (username: string, email: string, password: string) => {
    try {
      const registerData: UserRegisterRequest = {
        username,
        email,
        password,
      };

      const registerResponse = await userService.register(registerData);
      
      if (registerResponse.code !== 200) {
        return { 
          success: false, 
          message: registerResponse.message
        };
      }

      const loginData: UserLoginRequest = {
        username_or_email: username,
        password: password,
      };

      const loginResponse = await userService.login(loginData);
      
      if (loginResponse.code !== 200) {
        return { 
          success: false, 
          message: loginResponse.message
        };
      }

      const { token } = loginResponse.data;
      
      // 先存储 token
      await storage.setItem('token', token);
      
      const userId = getUserIdFromToken(token);
      
      if (!userId) {
        return { 
          success: false, 
          message: '登录失败：无效的 token'
        };
      }

      // 确保 token 已经被存储后再获取用户信息
      await new Promise(resolve => setTimeout(resolve, 100));
      const userResponse = await userService.getUser(userId);
      
      if (userResponse.code !== 200) {
        return { 
          success: false, 
          message: userResponse.message
        };
      }

      const user = userResponse.data;

      // 存储用户信息
      await storage.setItem('user', JSON.stringify(user));

      dispatch({
        type: 'SET_USER',
        payload: { user, token },
      });

      return { success: true, message: '注册成功' };
    } catch (error: any) {
      console.error('Registration error:', error);
      return { 
        success: false, 
        message: error.message || '注册失败，请重试'
      };
    }
  }, []);

  // 更新用户资料
  const updateProfile = useCallback(async (data: Partial<User>) => {
    try {
      if (!state.user?.id) {
        throw new Error('用户未登录');
      }

      const updateData: UserUpdateRequest = {
        nickname: data.username,
        avatar: data.avatar,
        bio: data.bio,
      };

      const response = await userService.updateUser(Number(state.user.id), updateData);
      const updatedUser = response.data;

      await storage.setItem('user', JSON.stringify(updatedUser));
      dispatch({ type: 'UPDATE_USER', payload: updatedUser });
    } catch (error: any) {
      const errorMessage = error.message || '更新资料失败，请重试';
      dispatch({ type: 'SET_ERROR', payload: errorMessage });
    }
  }, [state.user?.id]);

  const value = {
    ...state,
    login,
    logout,
    register,
    updateProfile,
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

// Hook
export function useAuth() {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
} 